package group.rober.saber.jdbc.accessor.impl;

import group.rober.saber.jdbc.DefaultNameConverter;
import group.rober.saber.jdbc.NameConverter;
import group.rober.saber.jdbc.accessor.DataAccessor;
import group.rober.saber.jdbc.accessor.listener.DeleteListener;
import group.rober.saber.jdbc.accessor.listener.InsertListener;
import group.rober.saber.jdbc.accessor.listener.UpdateListener;
import group.rober.saber.kit.MapKit;
import group.rober.saber.kit.ValidateKit;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

/**
 * DataBox数据读写
 * Created by tisir<yangsong158@qq.com> on 2017-06-02
 */
public class DataAccessorImpl implements DataAccessor {
    protected JdbcTemplate jdbcTemplate;
    private NameConverter nameConverter = new DefaultNameConverter();
    private boolean blankStringReplacedByNull = true;
    private String optimisticLockProperty = null; //乐观锁属性
    private InsertListener defaultInsertListener;
    private DeleteListener defaultDeleteListener;
    private UpdateListener defaultUpdateListener;

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public NameConverter getNameConverter() {
        return nameConverter;
    }

    public void setNameConverter(NameConverter nameConverter) {
        this.nameConverter = nameConverter;
    }

    public boolean isBlankStringReplacedByNull() {
        return blankStringReplacedByNull;
    }

    public void setBlankStringReplacedByNull(boolean blankStringReplacedByNull) {
        this.blankStringReplacedByNull = blankStringReplacedByNull;
    }

    public String getOptimisticLockProperty() {
        return optimisticLockProperty;
    }

    public void setOptimisticLockProperty(String optimisticLockProperty) {
        this.optimisticLockProperty = optimisticLockProperty;
    }

    public InsertListener getDefaultInsertListener() {
        return defaultInsertListener;
    }

    public void setDefaultInsertListener(InsertListener defaultInsertListener) {
        this.defaultInsertListener = defaultInsertListener;
    }

    public DeleteListener getDefaultDeleteListener() {
        return defaultDeleteListener;
    }

    public void setDefaultDeleteListener(DeleteListener defaultDeleteListener) {
        this.defaultDeleteListener = defaultDeleteListener;
    }

    public UpdateListener getDefaultUpdateListener() {
        return defaultUpdateListener;
    }

    public void setDefaultUpdateListener(UpdateListener defaultUpdateListener) {
        this.defaultUpdateListener = defaultUpdateListener;
    }

    protected MapDataAccessor getMapDataAccessor(String table){
        MapDataAccessor mapDataAccessor = new MapDataAccessor(table);
        mapDataAccessor.setJdbcTemplate(new NamedParameterJdbcTemplate(jdbcTemplate));
        mapDataAccessor.setNameConverter(nameConverter);
        mapDataAccessor.setBlankStringReplacedByNull(blankStringReplacedByNull);
        mapDataAccessor.setOptimisticLockProperty(optimisticLockProperty);
        return mapDataAccessor;
    }
    protected BeanDataAccessor getBeanDataAccessor(){
        return this.getBeanDataAccessor(null);
    }
    protected BeanDataAccessor getBeanDataAccessor(String table){
        BeanDataAccessor beanDataAccessor = new BeanDataAccessor();
        beanDataAccessor.setTable(table);
        beanDataAccessor.setJdbcTemplate(new NamedParameterJdbcTemplate(jdbcTemplate));
        beanDataAccessor.setNameConverter(nameConverter);
        beanDataAccessor.setBlankStringReplacedByNull(blankStringReplacedByNull);
        beanDataAccessor.setOptimisticLockProperty(optimisticLockProperty);
        return beanDataAccessor;
    }

    private boolean isMap(Class<?> classType){
        return Map.class.isAssignableFrom(classType);
    }

    public <T> T selectOne(Class<T> classType, String sql) {
        return selectOne(classType,sql,MapKit.newHashMap());
    }

    public <T> T selectOne(Class<T> classType, String sql, Map<String, Object> parameter) {
        List<T> listData = this.selectList(classType,sql,parameter);
        if(listData==null||listData.size()==0)return null;
        return listData.get(0);
    }

    public <T> T selectOne(Class<T> classType, String sql, String k1, Object v1) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        return this.selectOne(classType,sql,parameters);
    }

    public <T> T selectOne(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        return this.selectOne(classType,sql,parameters);
    }

    public <T> T selectOne(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        return this.selectOne(classType,sql,parameters);
    }

    public <T> T selectOne(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        return this.selectOne(classType,sql,parameters);
    }

    public <T> T selectOne(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        return this.selectOne(classType,sql,parameters);
    }

    public <T> T selectOne(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        return this.selectOne(classType,sql,parameters);
    }

    public <T> T selectOne(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6, String k7, Object v7) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        parameters.put(k7,v7);
        return this.selectOne(classType,sql,parameters);
    }

    public <T> T selectOne(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6, String k7, Object v7, String k8, Object v8) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        parameters.put(k7,v7);
        parameters.put(k8,v8);
        return this.selectOne(classType,sql,parameters);
    }

    public <T> T selectOne(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6, String k7, Object v7, String k8, Object v8, String k9, Object v9) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        parameters.put(k7,v7);
        parameters.put(k8,v8);
        parameters.put(k9,v9);
        return this.selectOne(classType,sql,parameters);
    }

    public <T> List<T> selectList(Class<T> classType, String sql) {
        return selectList(classType,sql,MapKit.newHashMap());
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> selectList(Class<T> classType, String sql, Map<String, Object> parameter) {
        if(!isMap(classType)){
            return getBeanDataAccessor().selectList(classType,sql,parameter);
        }else{
            return (List<T>) getMapDataAccessor("").selectList(sql,parameter);
        }
    }


    public Integer selectForInt(String sql, Map<String, Object> parameter) {
        NamedParameterJdbcTemplate npjt = new NamedParameterJdbcTemplate(jdbcTemplate);
        return npjt.queryForObject(sql.toString(), parameter, new RowMapper<Integer>() {
            public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
                return rs.getInt(1);
            }
        });
    }

    public Integer selectForInt(String sql, String k1, Object v1){
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        return this.selectForInt(sql,parameters);
    }

    public Integer selectForInt(String sql, String k1, Object v1, String k2, Object v2) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        return this.selectForInt(sql,parameters);
    }

    public Integer selectForInt(String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        return this.selectForInt(sql,parameters);
    }

    public Integer selectForInt(String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        return this.selectForInt(sql,parameters);
    }

    public Integer selectForInt(String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        return this.selectForInt(sql,parameters);
    }

    public Integer selectForInt(String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        return this.selectForInt(sql,parameters);
    }

    public Integer selectForInt(String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6, String k7, Object v7) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        parameters.put(k7,v7);
        return this.selectForInt(sql,parameters);
    }

    public Integer selectForInt(String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6, String k7, Object v7, String k8, Object v8) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        parameters.put(k7,v7);
        parameters.put(k8,v8);
        return this.selectForInt(sql,parameters);
    }

    public Integer selectForInt(String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6, String k7, Object v7, String k8, Object v8, String k9, Object v9) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        parameters.put(k7,v7);
        parameters.put(k8,v8);
        parameters.put(k9,v9);
        return this.selectForInt(sql,parameters);
    }

    public <T> List<T> selectList(Class<T> classType, String sql, String k1, Object v1) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        return this.selectList(classType,sql,parameters);
    }

    public <T> List<T> selectList(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        return this.selectList(classType,sql,parameters);
    }

    public <T> List<T> selectList(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        return this.selectList(classType,sql,parameters);
    }

    public <T> List<T> selectList(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        return this.selectList(classType,sql,parameters);
    }

    public <T> List<T> selectList(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        return this.selectList(classType,sql,parameters);
    }

    public <T> List<T> selectList(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        return this.selectList(classType,sql,parameters);
    }

    public <T> List<T> selectList(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6, String k7, Object v7) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        parameters.put(k7,v7);
        return this.selectList(classType,sql,parameters);
    }

    public <T> List<T> selectList(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6, String k7, Object v7, String k8, Object v8) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        parameters.put(k7,v7);
        parameters.put(k8,v8);
        return this.selectList(classType,sql,parameters);
    }

    public <T> List<T> selectList(Class<T> classType, String sql, String k1, Object v1, String k2, Object v2, String k3, Object v3, String k4, Object v4, String k5, Object v5, String k6, Object v6, String k7, Object v7, String k8, Object v8, String k9, Object v9) {
        Map<String,Object> parameters = MapKit.newLinkedHashMap();
        parameters.put(k1,v1);
        parameters.put(k2,v2);
        parameters.put(k3,v3);
        parameters.put(k4,v4);
        parameters.put(k5,v5);
        parameters.put(k6,v6);
        parameters.put(k7,v7);
        parameters.put(k8,v8);
        parameters.put(k9,v9);
        return this.selectList(classType,sql,parameters);
    }

    public int update(String sql) {
        return jdbcTemplate.update(sql);
    }

    public int update(String sql, Map<String, Object> entity) {
        NamedParameterJdbcTemplate npjt = new NamedParameterJdbcTemplate(jdbcTemplate);
        return npjt.update(sql,new MapSqlParameterSource(entity));
    }

    public int delete(String sql) {
        return jdbcTemplate.update(sql);
    }

    public int delete(String sql, Map<String, Object> entity) {
        NamedParameterJdbcTemplate npjt = new NamedParameterJdbcTemplate(jdbcTemplate);
        return npjt.update(sql,new MapSqlParameterSource(entity));
    }

    public <T> int insert(T entity) {
        return insert(entity,defaultInsertListener);
    }

    public <T> int insert(T entity, InsertListener<T> listener) {
        ValidateKit.isTrue(!isMap(entity.getClass()),"%s is not a javabean",entity.getClass().getName());
        if(listener!=null)listener.before(entity);
        int r = getBeanDataAccessor().insert(entity);
        if(listener!=null)listener.after(entity);
        return r;
    }

    public <T> int update(T entity) {
        return update(entity,defaultUpdateListener);
    }

    public <T> int update(T entity, UpdateListener<T> listener) {
        ValidateKit.isTrue(!isMap(entity.getClass()),"%s is not a javabean",entity.getClass().getName());
        return getBeanDataAccessor().update(entity,listener);
    }

    public <T> int save(T entity) {
        return save(entity,defaultInsertListener,defaultUpdateListener);
    }

    public <T> int save(T entity, InsertListener<T> insertListener, UpdateListener<T> updateListener) {
        ValidateKit.isTrue(!isMap(entity.getClass()),"%s is not a javabean",entity.getClass().getName());
        return getBeanDataAccessor().save(entity,insertListener,updateListener);
    }

    public <T> int delete(T entity) {
        return delete(entity,defaultDeleteListener);
    }

    public <T> int delete(T entity, DeleteListener<T> listener) {
        ValidateKit.isTrue(!isMap(entity.getClass()),"%s is not a javabean",entity.getClass().getName());
        return getBeanDataAccessor().delete(entity,listener);
    }

    public <T> int insert(String table, T entity) {
        return insert(table,entity,defaultInsertListener);
    }

    public <T> int insert(String table, T entity, InsertListener<T> listener) {
        ValidateKit.isTrue(!isMap(entity.getClass()),"%s is not a javabean",entity.getClass().getName());
        return getBeanDataAccessor(table).insert(entity,listener);
    }

    public <T> int update(String table, T entity) {
        return update(table,entity,defaultUpdateListener);
    }

    public <T> int update(String table, T entity, UpdateListener<T> listener) {
        ValidateKit.isTrue(!isMap(entity.getClass()),"%s is not a javabean",entity.getClass().getName());
        return getBeanDataAccessor(table).update(entity,listener);
    }

    public <T> int save(String table, T entity) {
        return save(table,entity,defaultInsertListener,defaultUpdateListener);
    }

    public <T> int save(String table, T entity, InsertListener<T> insertListener, UpdateListener<T> updateListener) {
        ValidateKit.isTrue(!isMap(entity.getClass()),"%s is not a javabean",entity.getClass().getName());
        return getBeanDataAccessor(table).save(entity,insertListener,updateListener);
    }

    public <T> int delete(String table, T entity) {
        return delete(table,entity,defaultDeleteListener);
    }

    public <T> int delete(String table, T entity, DeleteListener<T> listener) {
        ValidateKit.isTrue(!isMap(entity.getClass()),"%s is not a javabean",entity.getClass().getName());
        return getBeanDataAccessor(table).delete(entity,listener);
    }

    public <T> int insert(List<T> entityList) {
        return insert(entityList,defaultInsertListener);
    }

    public <T> int insert(List<T> entityList, InsertListener<List<T>> listener) {
        return getBeanDataAccessor().insert(entityList,listener);
    }

    public <T> int update(List<T> entityList) {
        return update(entityList,defaultUpdateListener);
    }

    public <T> int update(List<T> entityList, UpdateListener<List<T>> listener) {
        return getBeanDataAccessor().update(entityList,listener);
    }

    public <T> int save(List<T> entityList) {
        return save(entityList,defaultInsertListener,defaultUpdateListener);
    }

    public <T> int save(List<T> entityList, InsertListener<List<T>> insertListener, UpdateListener<List<T>> updateListener) {
        return getBeanDataAccessor().save(entityList,insertListener,updateListener);
    }

    public <T> int delete(List<T> entityList) {
        return delete(entityList,defaultDeleteListener);
    }

    public <T> int delete(List<T> entityList, DeleteListener<List<T>> listener) {
        return getBeanDataAccessor().delete(entityList,listener);
    }

    public <T> int insert(String table, List<T> entityList) {
        return insert(table,entityList,defaultInsertListener);
    }

    public <T> int insert(String table, List<T> entityList, InsertListener<List<T>> listener) {
        return getBeanDataAccessor(table).insert(entityList,listener);
    }

    public <T> int update(String table, List<T> entityList) {
        return update(table,entityList,defaultUpdateListener);
    }

    public <T> int update(String table, List<T> entityList, UpdateListener<List<T>> listener) {
        return getBeanDataAccessor(table).update(entityList,listener);
    }

    public <T> int save(String table, List<T> entityList) {
        return save(table,entityList,defaultInsertListener,defaultUpdateListener);
    }

    public <T> int save(String table, List<T> entityList, InsertListener<List<T>> insertListener, UpdateListener<List<T>> updateListener) {
        return getBeanDataAccessor(table).save(entityList,insertListener,updateListener);
    }

    public <T> int delete(String table, List<T> entityList) {
        return delete(table,entityList,defaultDeleteListener);
    }

    public <T> int delete(String table, List<T> entityList, DeleteListener<List<T>> listener) {
        return getBeanDataAccessor(table).delete(entityList,listener);
    }

    public int insertMap(String table, Map<String, Object> entity) {
        return insertMap(table,entity,defaultInsertListener);
    }

    public int insertMap(String table, Map<String, Object> entity, InsertListener<Map<String, Object>> listener) {
        return getMapDataAccessor(table).insert(entity,listener);
    }

    public int updateMap(String table, Map<String, Object> entity, Map<String, Object> keyAttributes) {
        return updateMap(table,entity,keyAttributes,defaultUpdateListener);
    }

    public int updateMap(String table, Map<String, Object> entity, Map<String, Object> keyAttributes, UpdateListener<Map<String, Object>> listener) {
        return getMapDataAccessor(table).update(entity,keyAttributes,listener);
    }

    public int saveMap(String table, Map<String, Object> entity, Map<String, Object> keyAttributes) {
        return saveMap(table,entity,keyAttributes,defaultInsertListener,defaultUpdateListener);
    }

    public int saveMap(String table, Map<String, Object> entity, Map<String, Object> keyAttributes, InsertListener<Map<String, Object>> insertListener, UpdateListener<Map<String, Object>> updateListener) {
        return getMapDataAccessor(table).save(entity,keyAttributes,insertListener,updateListener);
    }

    public int deleteMap(String table, Map<String, Object> keyAttributes) {
        return deleteMap(table,keyAttributes,defaultDeleteListener);
    }

    public int deleteMap(String table, Map<String, Object> keyAttributes, DeleteListener<Map<String, Object>> listener) {
        return getMapDataAccessor(table).delete(keyAttributes,listener);
    }

    public int insertMap(String table, List<Map<String, Object>> entityList) {
        return insertMap(table,entityList,defaultInsertListener);
    }

    public int insertMap(String table, List<Map<String, Object>> entityList, InsertListener<List<Map<String, Object>>> listener) {
        return getMapDataAccessor(table).insert(entityList,listener);
    }

    public int updateMap(String table, List<Map<String, Object>> entityList, List<Map<String, Object>> keyAttributesList) {
        return updateMap(table, entityList, keyAttributesList, defaultUpdateListener);
    }

    public int updateMap(String table, List<Map<String, Object>> entityList, List<Map<String, Object>> keyAttributesList, UpdateListener<List<Map<String, Object>>> listener) {
        return getMapDataAccessor(table).update(entityList,keyAttributesList,listener);
    }

    public int saveMap(String table, List<Map<String, Object>> entityList, List<Map<String, Object>> keyAttributesList) {
        return saveMap(table, entityList, keyAttributesList,defaultInsertListener,defaultUpdateListener);
    }

    public int saveMap(String table, List<Map<String, Object>> entityList, List<Map<String, Object>> keyAttributesList, InsertListener<List<Map<String, Object>>> insertListener, UpdateListener<List<Map<String, Object>>> updateListener) {
        return getMapDataAccessor(table).save(entityList,keyAttributesList,insertListener,updateListener);
    }

    public int deleteMap(String table,List<Map<String, Object>> keyAttributesList) {
        return deleteMap(table, keyAttributesList,defaultDeleteListener);
    }

    public int deleteMap(String table, List<Map<String, Object>> keyAttributesList, DeleteListener<List<Map<String, Object>>> listener) {
        return getMapDataAccessor(table).delete(keyAttributesList,listener);
    }

}
